﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace CustomControlPractice.MVP
{
    public enum SearchType { ByUnicard = 0, ByName }

    public class Presenter
    {
        private readonly IView view;
        private readonly Modal modal = new Modal();

        private delegate IEnumerable<Case> CaseSearchHandler(List<Case> cases);
        private Dictionary<SearchType, CaseSearchHandler> searchHandlers;


        public Presenter(IView view)
        {
            if (view == null) throw new ArgumentNullException("view");
            this.view = view;
            BuildSearchHandlers();
        }

        public void LoadAllCases()
        {
            List<Case> cases = modal.GetAllCases();
            view.RenderCases(cases);
        }

        public void Search()
        {
            if(!searchHandlers.ContainsKey(view.SearchType))
            {
                throw new NotSupportedException("Not supported search type.");
            }
            List<Case> cases = modal.GetAllCases();
            var result = searchHandlers[view.SearchType](cases);
            view.RenderCases(result);
        }

        public void Sort()
        {
            List<Case> cases = modal.GetAllCases();
            var param = Expression.Parameter(typeof(Case), typeof(Case).Name);
            var sortExpression = Expression.Lambda<Func<Case, object>>(Expression.Convert(Expression.Property(param, view.SortExpression), typeof(object)), param);
            IOrderedQueryable<Case> result;
            if (view.Direction == Direction.Ascending)
            {
                result = cases.AsQueryable().OrderBy(sortExpression);
            }
            else
            {
                result = cases.AsQueryable().OrderByDescending(sortExpression);
            }
            view.RenderCases(result);
        }



        private void BuildSearchHandlers()
        {
            searchHandlers = new Dictionary<SearchType, CaseSearchHandler>
                                 {
                                     {SearchType.ByUnicard, SearchByUnicard},
                                     {SearchType.ByName, SearchByName}
                                 };
        }

        private IEnumerable<Case> SearchByName(List<Case> cases)
        {
            var result = from @case in cases
                         where @case.PatientName == view.SearchContent
                         select @case;
            return result;
        }

        private IEnumerable<Case> SearchByUnicard(List<Case> cases)
        {
            var result = from @case in cases
                         where @case.PatientName == view.SearchContent
                         select @case;
            return result;
        }
    }
}